package com.ruoyi.bussine.service.integration.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.bussine.common.enums.integration.PathEnum;
import com.ruoyi.bussine.domain.dto.wechat.*;
import com.ruoyi.bussine.service.integration.WeChatService;
import com.ruoyi.bussine.utils.ModuleHttpUtil;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhengyz
 * 微信服务实现
 */
@Slf4j
@Service
public class WeChatServiceImpl implements WeChatService {

    @Autowired
    private ModuleHttpUtil moduleHttpUtil;

    @Override
    public Jscode2sessionRespDTO getSessionByCode(Jscode2sessionReqDTO jscode2sessionReqDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", jscode2sessionReqDTO.getAppid());
        paramMap.put("secret", jscode2sessionReqDTO.getSecret());
        // 固定写死
        paramMap.put("grant_type", "authorization_code");
        paramMap.put("js_code", jscode2sessionReqDTO.getJsCode());
        String result = moduleHttpUtil.get(PathEnum.WECHAT_JSCODE2SESSION, paramMap);
        return JSONUtil.toBean(result, Jscode2sessionRespDTO.class);
    }

    @Override
    public WeChatTokenRespDTO getToken(MiniProgramBaseInfoDTO programBaseInfoDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", programBaseInfoDTO.getAppid());
        paramMap.put("secret", programBaseInfoDTO.getSecret());
        // 固定写死
        paramMap.put("grant_type", "client_credential");
        String result = moduleHttpUtil.get(PathEnum.WECHAT_GET_TOKEN, paramMap);
        return JSONUtil.toBean(result, WeChatTokenRespDTO.class);
    }

    @Override
    public String generateUrlLink(String accessToken, WeChatUrlLinkReqDTO weChatUrlLinkReqDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        String result = moduleHttpUtil.post(PathEnum.WECHAT_URL_LINK, paramMap, JSONUtil.toJsonStr(weChatUrlLinkReqDTO));
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("errcode") != 0) {
            if (jsonObject.getInteger("errcode") == 85079) {
                throw new ServiceException("小程序没有线上版本，即小程序尚未发布，不可进行该操作");
            }
            throw new ServiceException(jsonObject.getString("errmsg"), jsonObject.getInteger("errcode"));
        }
        return jsonObject.getString("urlLink");
    }

    /**
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html
     * {
     * "page": "pages/tabbar/home/index",
     * "scene": "a=1",
     * "check_path": false,
     * "env_version": "trial"
     * }
     *
     * @param accessToken
     * @param jsonMap
     * @return
     */
    @Override
    public byte[] getwxacodeunlimit(String accessToken, Map<String, Object> jsonMap) {
        log.info("getwxacodeunlimit accessToken = {}", accessToken);
        log.info("getwxacodeunlimit jsonMap = {}", jsonMap);
        return HttpUtil
                .createPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken)
                .body(JSONUtil.toJsonStr(jsonMap))
                .execute()
                .bodyBytes();
    }

    /**
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
     *
     * @param accessToken
     * @param code
     * @return
     */
    @Override
    public String getUserPhoneNumber(String accessToken, String code) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("code", code);
        String result = moduleHttpUtil.post(PathEnum.WECHAT_GET_PHONE_NUMBER, paramMap, JSONUtil.toJsonStr(jsonMap));
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("errcode") != 0) {
            throw new ServiceException(jsonObject.getString("errmsg"), jsonObject.getInteger("errcode"));
        }
        return jsonObject.getJSONObject("phone_info").getString("purePhoneNumber");
    }

    @Override
    public void sendOrder(String accessToken, ShippingInfoReqDTO shippingInfoReqDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        String result = moduleHttpUtil.post(PathEnum.WECHAT_UPLOAD_SHIPPING_INFO, paramMap, JSONUtil.toJsonStr(shippingInfoReqDTO));
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getInteger("errcode") != 0) {
            throw new ServiceException(jsonObject.getString("errmsg"), jsonObject.getInteger("errcode"));
        }
    }

    public Jscode2sessionRespDTO getPhoneInfoByCode(Jscode2sessionReqDTO jscode2sessionReqDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", jscode2sessionReqDTO.getSecret());
        paramMap.put("code", jscode2sessionReqDTO.getJsCode());
        String result = moduleHttpUtil.post(PathEnum.WECHAT_PHONE_INFO, paramMap, null);
        return JSONUtil.toBean(result, Jscode2sessionRespDTO.class);
    }
}